package system

import (
	"github.com/gin-gonic/gin"
	"github.com/google/martian/log"
	"net/http"
	"strconv"
	"vben-api/api/rpc"
	"vben-api/pkg/svc"
	common "vben-common"
	"vben-common/errs"
	systemServiceV1 "vben-grpc-common/vben-admin/types/system.service.v1"
)

type Department struct {
	svcCtx *svc.ServiceContext
}

func NewDepartment(svcCtx *svc.ServiceContext) *Department {
	return &Department{
		svcCtx: svcCtx,
	}
}

func (d *Department) UpdateDept(c *gin.Context) {
	result := &common.Result{}
	var deptRequest systemServiceV1.UpdateDeptRequest
	if err := c.ShouldBind(&deptRequest); err != nil {
		c.JSON(http.StatusOK, result.Fail(400, "参数错误"))
		return
	}
	deptRequest.UpdatedBy = "admin"
	res, err := rpc.SystemServiceClient.UpdateDept(c, &deptRequest)
	if err != nil {
		code, msg := errs.ParseGrpcError(err)
		c.JSON(http.StatusOK, result.Fail(code, msg))
		return
	}
	c.JSON(http.StatusOK, result.Success(res))
}

func (d *Department) DeleteDept(c *gin.Context) {
	result := &common.Result{}

	var deptRequest systemServiceV1.DeleteDeptRequest
	err := c.ShouldBind(&deptRequest)
	if err != nil {
		c.JSON(http.StatusBadRequest, result.Fail(400, "参数错误"))
	}
	deptRequest.DeletedBy = "admin"

	res, err := rpc.SystemServiceClient.DeleteDept(c, &deptRequest)
	if err != nil {
		code, msg := errs.ParseGrpcError(err)
		c.JSON(http.StatusOK, result.Fail(code, msg))
		return
	}
	c.JSON(http.StatusOK, result.Success(res))
}

func (d *Department) CreateDept(ctx *gin.Context) {
	result := &common.Result{}
	var deptRequest systemServiceV1.CreateDeptRequest
	if err := ctx.ShouldBind(&deptRequest); err != nil {
		ctx.JSON(http.StatusBadRequest, result.Fail(400, "参数错误"))
		return
	}
	res, err := rpc.SystemServiceClient.CreateDept(ctx, &deptRequest)
	if err != nil {
		code, msg := errs.ParseGrpcError(err)
		ctx.JSON(http.StatusBadRequest, result.Fail(code, msg))
		return
	}
	ctx.JSON(http.StatusOK, result.Success(res))
}

func (d *Department) GetDeptInfo(ctx *gin.Context) {
	result := &common.Result{}

	// 获取Get请求参数id
	id := ctx.Query("id")
	log.Infof("id: %s", id)

	deptId, err := strconv.ParseInt(id, 10, 64)
	if err != nil {
		ctx.JSON(http.StatusOK, result.Fail(400, "id参数错误"))
		return
	}

	param := &systemServiceV1.DeptInfoRequest{
		Id: deptId,
	}
	info, err := rpc.SystemServiceClient.GetDeptInfo(ctx, param)

	if err != nil {
		code, msg := errs.ParseGrpcError(err)
		ctx.JSON(http.StatusOK, result.Fail(code, msg))
		return
	}
	ctx.JSON(http.StatusOK, result.Success(info))
}

// GetDeptList 是一个处理部门列表查询请求的方法。
// 它使用gin框架提供的Context来处理HTTP请求并返回响应。
// 参数:
//
//	ctx *gin.Context: gin框架的上下文对象，用于访问请求信息、发送响应以及进行中间件操作。
func (d *Department) GetDeptList(ctx *gin.Context) {
	result := &common.Result{}
	name := ctx.Query("name")
	// 如果status为空，则默认为 1
	strStatus := ctx.DefaultQuery("status", "1")

	log.Infof("name: %s, status: %s", name, strStatus)
	intStatus, _ := strconv.ParseInt(strStatus, 10, 32)

	param := &systemServiceV1.DeptListRequest{
		Name:   name,
		Status: int32(intStatus),
	}

	list, err := rpc.SystemServiceClient.GetDeptList(ctx, param)
	if err != nil {
		code, msg := errs.ParseGrpcError(err)
		ctx.JSON(http.StatusBadRequest, result.Fail(code, msg))
		return
	}
	data := list.Data
	deptTree := d.transformToDeptNode(data)
	ctx.JSON(http.StatusOK, result.Success(deptTree))
}

func (d *Department) transformToDeptNode(data []*systemServiceV1.DeptListData) []*DeptNode {
	// DeptListData转换为DeptNode
	var deptNode = make([]*DeptNode, 0)
	for _, item := range data {
		node := &DeptNode{
			Id:         item.Id,
			Name:       item.Name,
			ParentId:   item.ParentId,
			ParentName: "",
			SortNo:     item.SortNo,
			Status:     item.Status,
			CreatedAt:  item.CreatedAt,
			Remark:     item.Remark,
			Children:   make([]*DeptNode, 0),
		}
		if item.ParentId == 0 {
			node.Children = d.buildDeptNodeChildren(item.Children, item.Id, item.Name)
		}
		deptNode = append(deptNode, node)
	}
	return deptNode
}

func (d *Department) buildDeptNodeChildren(data []*systemServiceV1.DeptListData, parentId int64, parentName string) []*DeptNode {
	var childNode = make([]*DeptNode, 0)
	if len(data) == 0 {
		return childNode
	}

	for _, item := range data {
		if item.ParentId == parentId {
			node := &DeptNode{
				Id:         item.Id,
				Name:       item.Name,
				ParentId:   item.ParentId,
				ParentName: parentName,
				SortNo:     item.SortNo,
				Status:     item.Status,
				CreatedAt:  item.CreatedAt,
				Remark:     item.Remark,
				Children:   make([]*DeptNode, 0),
			}
			node.Children = d.buildDeptNodeChildren(item.Children, item.Id, item.Name)
			childNode = append(childNode, node)
		}
	}
	return childNode
}

type DeptNode struct {
	Id         int64       `json:"id"`
	Name       string      `json:"name"`
	ParentId   int64       `json:"parent_id"`
	ParentName string      `json:"parent_name"`
	SortNo     int64       `json:"sort_no"`
	Status     int32       `json:"status"`
	CreatedAt  string      `json:"created_at"`
	Remark     string      `json:"remark"`
	Children   []*DeptNode `json:"children,omitempty"`
}
